<script setup lang="ts">
import type { FormInstance } from 'ant-design-vue';

import { computed, reactive, ref, watch } from 'vue';

import {
  createOAuth2ClientApi,
  getAuthMethodsApi,
  getGrantTypesApi,
  getScopesApi,
  updateOAuth2ClientApi,
  type OAuth2ClientDTO,
  type OptionItem,
} from '#/api/core/oauth2-client';

import {
  Divider,
  Form,
  FormItem,
  Input,
  InputPassword,
  message,
  Modal,
  Select,
  SelectOption,
  Textarea,
} from 'ant-design-vue';

interface Props {
  visible: boolean;
  clientData?: OAuth2ClientDTO | null;
}

const props = defineProps<Props>();
const emit = defineEmits(['update:visible', 'success']);

const formRef = ref<FormInstance>();
const confirmLoading = ref(false);

// 选项数据
const grantTypeOptions = ref<OptionItem[]>([]);
const authMethodOptions = ref<OptionItem[]>([]);
const scopeOptions = ref<OptionItem[]>([]);

// 表单数据
const formData = reactive<{
  id?: string;
  clientId: string;
  clientSecret: string;
  clientName: string;
  clientAuthenticationMethods: string[];
  authorizationGrantTypes: string[];
  redirectUris: string;
  scopes: string[];
}>({
  clientId: '',
  clientSecret: '',
  clientName: '',
  clientAuthenticationMethods: [],
  authorizationGrantTypes: [],
  redirectUris: '',
  scopes: [],
});

// 表单验证规则
const rules = {
  clientId: [
    { required: true, message: '请输入客户端ID', trigger: 'blur' },
    { min: 3, max: 100, message: '客户端ID长度为3-100个字符', trigger: 'blur' },
  ],
  clientSecret: [
    {
      trigger: 'blur',
      validator: (_rule: any, value: string) => {
        if (isEdit.value && !value) {
          // 编辑模式下，如果不填写密钥，则不修改密钥
          return Promise.resolve();
        }
        if (!value) {
          return Promise.reject(new Error('请输入客户端密钥'));
        }
        if (value.length < 8) {
          return Promise.reject(new Error('客户端密钥至少8个字符'));
        }
        return Promise.resolve();
      },
    },
  ],
  clientName: [
    { required: true, message: '请输入客户端名称', trigger: 'blur' },
    { max: 200, message: '客户端名称最多200个字符', trigger: 'blur' },
  ],
  authorizationGrantTypes: [
    { required: true, message: '请选择授权类型', trigger: 'change', type: 'array' },
  ],
  clientAuthenticationMethods: [
    { required: true, message: '请选择认证方法', trigger: 'change', type: 'array' },
  ],
  scopes: [
    { required: true, message: '请选择权限范围', trigger: 'change', type: 'array' },
  ],
  redirectUris: [
    { required: true, message: '请输入重定向URI', trigger: 'blur' },
  ],
};

const isEdit = computed(() => !!props.clientData?.id);
const modalTitle = computed(() => (isEdit.value ? '编辑客户端' : '新增客户端'));

// 加载选项数据
async function loadOptions() {
  try {
    const [grantTypes, authMethods, scopes] = await Promise.all([
      getGrantTypesApi(),
      getAuthMethodsApi(),
      getScopesApi(),
    ]);
    grantTypeOptions.value = grantTypes;
    authMethodOptions.value = authMethods;
    scopeOptions.value = scopes;
  } catch (error) {
    console.error('加载选项数据失败:', error);
    message.error('加载选项数据失败');
  }
}

// 监听客户端数据变化
watch(
  () => props.clientData,
  (newVal) => {
    console.log('=== 客户端数据变化 ===');
    console.log('props.clientData:', newVal);
    console.log('props.visible:', props.visible);

    if (newVal) {
      // 编辑模式：填充数据
      console.log('编辑模式 - 填充数据:', {
        id: newVal.id,
        clientId: newVal.clientId,
        clientName: newVal.clientName,
        clientAuthenticationMethods: newVal.clientAuthenticationMethods,
        authorizationGrantTypes: newVal.authorizationGrantTypes,
        redirectUris: newVal.redirectUris,
        scopes: newVal.scopes,
      });

      Object.assign(formData, {
        id: newVal.id,
        clientId: newVal.clientId,
        clientSecret: '', // 编辑时不显示原密钥
        clientName: newVal.clientName,
        clientAuthenticationMethods: newVal.clientAuthenticationMethods || [],
        authorizationGrantTypes: newVal.authorizationGrantTypes || [],
        redirectUris: newVal.redirectUris?.join('\n') || '',
        scopes: newVal.scopes || [],
      });

      console.log('填充后的 formData:', { ...formData });
    } else {
      // 新增模式：重置表单
      console.log('新增模式 - 重置表单');
      resetForm();
    }
    console.log('===================');
  },
  { immediate: true },
);

// 监听弹窗显示
watch(
  () => props.visible,
  (visible) => {
    if (visible) {
      loadOptions();
    }
  },
);

// 重置表单
function resetForm() {
  formData.id = undefined;
  formData.clientId = '';
  formData.clientSecret = '';
  formData.clientName = '';
  formData.clientAuthenticationMethods = [];
  formData.authorizationGrantTypes = [];
  formData.redirectUris = '';
  formData.scopes = [];
  formRef.value?.clearValidate();
}

// 取消
function handleCancel() {
  emit('update:visible', false);
  resetForm();
}

// 确定
async function handleOk() {
  try {
    await formRef.value?.validate();
    confirmLoading.value = true;

    const submitData: any = {
      clientId: formData.clientId,
      clientName: formData.clientName,
      clientAuthenticationMethods: formData.clientAuthenticationMethods,
      authorizationGrantTypes: formData.authorizationGrantTypes,
      redirectUris: formData.redirectUris.split('\n').filter((uri) => uri.trim()),
      scopes: formData.scopes,
      // 添加默认的 client_settings 和 token_settings
      clientSettings: {},
      tokenSettings: {},
    };

    // 只有在填写了密钥时才提交密钥字段
    if (formData.clientSecret) {
      submitData.clientSecret = formData.clientSecret;
    }

    if (isEdit.value) {
      await updateOAuth2ClientApi(formData.id!, submitData);
      message.success('编辑成功');
    } else {
      await createOAuth2ClientApi(submitData);
      message.success('新增成功');
    }

    emit('success');
    handleCancel();
  } catch (error: any) {
    // 表单验证失败
    if (error?.errorFields) {
      console.log('表单验证失败:', error.errorFields);
      return;
    }
    // API 请求失败
    console.error('保存客户端失败:', error);
    message.error(error?.message || '保存客户端失败');
  } finally {
    confirmLoading.value = false;
  }
}
</script>

<template>
  <Modal
    :open="visible"
    :title="modalTitle"
    :confirm-loading="confirmLoading"
    width="700px"
    @cancel="handleCancel"
    @ok="handleOk"
  >
    <Form
      ref="formRef"
      :model="formData"
      :rules="rules"
      :label-col="{ span: 6 }"
      :wrapper-col="{ span: 16 }"
    >
      <!-- 基本信息 -->
      <Divider orientation="left">基本信息</Divider>

      <FormItem label="客户端ID" name="clientId">
        <Input
          v-model:value="formData.clientId"
          :disabled="isEdit"
          placeholder="请输入客户端ID（3-100个字符）"
        />
      </FormItem>

      <FormItem label="客户端名称" name="clientName">
        <Input
          v-model:value="formData.clientName"
          placeholder="请输入客户端名称"
          :maxlength="200"
          show-count
        />
      </FormItem>

      <FormItem label="客户端密钥" name="clientSecret">
        <InputPassword
          v-model:value="formData.clientSecret"
          :placeholder="isEdit ? '留空则不修改密钥' : '请输入客户端密钥（至少8个字符）'"
        />
        <template v-if="isEdit" #extra>
          <span class="text-xs text-gray-500">
            编辑时留空则不修改密钥
          </span>
        </template>
      </FormItem>

      <!-- OAuth2 配置 -->
      <Divider orientation="left">OAuth2 配置</Divider>

      <FormItem label="授权类型" name="authorizationGrantTypes">
        <Select
          v-model:value="formData.authorizationGrantTypes"
          mode="multiple"
          placeholder="请选择授权类型"
          :max-tag-count="2"
          style="width: 100%"
        >
          <SelectOption
            v-for="option in grantTypeOptions"
            :key="option.value"
            :value="option.value"
          >
            {{ option.label }}
          </SelectOption>
        </Select>
      </FormItem>

      <FormItem label="认证方法" name="clientAuthenticationMethods">
        <Select
          v-model:value="formData.clientAuthenticationMethods"
          mode="multiple"
          placeholder="请选择认证方法"
          :max-tag-count="2"
          style="width: 100%"
        >
          <SelectOption
            v-for="option in authMethodOptions"
            :key="option.value"
            :value="option.value"
          >
            {{ option.label }}
          </SelectOption>
        </Select>
      </FormItem>

      <FormItem label="权限范围" name="scopes">
        <Select
          v-model:value="formData.scopes"
          mode="multiple"
          placeholder="请选择权限范围"
          :max-tag-count="2"
          style="width: 100%"
        >
          <SelectOption
            v-for="option in scopeOptions"
            :key="option.value"
            :value="option.value"
          >
            {{ option.label }}
          </SelectOption>
        </Select>
      </FormItem>

      <FormItem label="重定向URI" name="redirectUris">
        <Textarea
          v-model:value="formData.redirectUris"
          :rows="4"
          placeholder="请输入重定向URI，每行一个&#10;例如：&#10;http://localhost:8080/callback&#10;https://example.com/oauth2/callback"
        />
        <template #extra>
          <span class="text-xs text-gray-500">
            多个URI请换行输入，用于OAuth2授权后的回调地址
          </span>
        </template>
      </FormItem>
    </Form>
  </Modal>
</template>

<style scoped>
:deep(.ant-divider-horizontal.ant-divider-with-text-left) {
  margin: 16px 0;
  font-weight: 500;
  color: rgba(0, 0, 0, 0.85);
}

:deep(.ant-form-item) {
  margin-bottom: 20px;
}
</style>

